#include "cledMatrixRGB.h"
#include "cledMatrix.h"
#include "UGUI/ugui.h"
#include "LCD/lcd.h"
#include "cledMatrixRGB.h"
#include "Curve/hsv.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>

/*************************************************************************************************\
|        Bloom [9]                                                                              |
\*************************************************************************************************/
struct Flower {
    hsv_t hsv;
    float hue;
    float speed_mult;// = 1.f;
};
static struct Flower flowers[41*41];
static hsv_t RandomHSVColor()
{
    hsv_t hsv;

    hsv.hue = rand() % 360;
    hsv.saturation = 255;
    hsv.value = 255;

    return hsv;
}
static void Bloom_UpdateFlowers(void)
{
    float delta = (float) mParams.Speed / (float) mParams.FPS;

    for(unsigned int i = 0; i < (sizeof(flowers)/sizeof(flowers[0])); i++)
    {
        struct Flower* flower = &flowers[i];
        flower->hue += (flower->speed_mult * delta);
        flower->hsv.hue = (int) flower->hue % 360;
    }
}


static void Bloom_Reset(void)
{
    //flowers.clear();
    memset(flowers, 0x000, sizeof(flowers));

    //for(ControllerZone* controller_zone: controller_zones)
    {
        //std::vector<Flower> zone_flowers;

        for(unsigned int i = 0; i < (sizeof(flowers)/sizeof(flowers[0])); i++)
        {
            struct Flower* flower = &flowers[i];
            flower->hsv = /*ColorUtils::*/RandomHSVColor();
            flower->hue = flower->hsv.hue;
            flower->speed_mult = ((double) rand() / (RAND_MAX)) + 1;
            flower->speed_mult = 1.f;
            //zone_flowers.push_back(flower);
        }

        //flowers.push_back(zone_flowers);
    }
}
void cledMatrixBloom_Init(void)    // 花朵
{
    mParams.time = 1000.0;
    mParams.FPS = 60;
    mParams.Speed = 100;
    mParams.Slider2Val = 30;
    mParams.shape = 0;
    mParams.progress = 0.f;
    Bloom_Reset();
}
void cledMatrixBloom(const uint32_t cols, const uint32_t rows)    // 花朵
{
//    if(flowers[i].size() != controller_zone->size())
//    {
//        Reset();
//    }

    Bloom_UpdateFlowers();
    for (uint32_t col_id = 0; col_id < cols; col_id++)
    {
        for (uint32_t row_id = 0; row_id < rows; row_id++)
        {
           int idx = (row_id * cols) + col_id;
           //int LedID = controller_zone->map()[idx];
           //int LedID = (row_id * cols) + col_id;
           uint32_t color = hsv2rgb(&flowers[idx].hsv);
           //controller_zone->SetLED(start_idx + LedID, color, Brightness);
           ugui_pset(col_id, row_id, color);
        }
    }
}

/*************************************************************************************************\
|        Lightning [9]                                                                              |
\*************************************************************************************************/
enum lightning_mode_value
{
    WHOLE_ZONE  = 0,
    PER_LED     = 1
};
static hsv_t Lightnings[41*41];
static enum lightning_mode_value lightning_mode = WHOLE_ZONE;//WHOLE_ZONE;

static void Lightning_OnControllerZonesListChanged(void)
{
    //Lightnings.clear();
    memset(&Lightnings, 0x00, sizeof(Lightnings));

    //for(ControllerZone* controller_zone: controller_zones)
    {
        //hsv_t leds;

        for(unsigned int i = 0; i < 41*41; i++)
        {
            hsv_t* lightning;

            lightning = &Lightnings[i];
            lightning->value = 0;
            lightning->hue = 0;//UserHSV.hue;
            lightning->saturation = 0;//UserHSV.saturation;
            //leds.push_back(lightning);
        }

        //Lightnings[controller_zone] = leds;
    }
}
void cledMatrixLightning_Init(void)    // 闪电
{
    mParams.time = 1000.0;
    mParams.FPS = 60;
    mParams.Speed = 20;
    mParams.Slider2Val = 10;
    mParams.shape = 0;
    mParams.progress = 0.f;
}
static uint32_t Lightning_TriggerLightning(int n)
{
    int Decay = mParams.Slider2Val;

    float decrease = 1 + Decay/(float) mParams.FPS;

    unsigned int mod = lightning_mode == WHOLE_ZONE ? 1000 : 1000 * 41*41;//z->leds_count();

//    Lightnings[n].value = ((unsigned int)(rand() % mod)) < mParams.Speed ?
//                std::min<unsigned char>(255, RandomColorsEnabled ? 255: UserHSV.value) :
//                Lightnings[z][n].value > 0 ?  Lightnings[z][n].value / decrease : 0;
    Lightnings[n].value = ((unsigned int)(rand() % mod)) < mParams.Speed ?
                255 : Lightnings[n].value > 0 ?  Lightnings[n].value / decrease : 0;

    //if(RandomColorsEnabled)
    {
        if(Lightnings[n].value == 0)
        {
            Lightnings[n].hue = rand() % 360;
            Lightnings[n].saturation = rand() % 255;
        }
    }
//    else
//    {
//        Lightnings[z][n].hue = UserHSV.hue;
//        Lightnings[z][n].saturation = UserHSV.saturation;
//    }

    return (hsv2rgb(&Lightnings[n]));
}

void cledMatrixLightning(const uint32_t cols, const uint32_t rows)    // 闪电
{
    if(lightning_mode == WHOLE_ZONE)
    {
        //for(ControllerZone* controller_zone : controller_zones)
        {
            //if(controller_zone->leds_count() > 0)
            {
                uint32_t color = Lightning_TriggerLightning(0);
                //controller_zone->SetAllZoneLEDs(color, Brightness);
                for (uint32_t col_id = 0; col_id < cols; col_id++)
                {
                    for (uint32_t row_id = 0; row_id < rows; row_id++)
                    {
                       ugui_pset(col_id, row_id, color);
                    }
                }
            }
        }
    }
    else if(lightning_mode == PER_LED)
    {
        //for(ControllerZone* controller_zone : controller_zones)
        {
            for(unsigned int i = 0; i < cols*rows; i++)
            {
                uint32_t color = Lightning_TriggerLightning(i);
                //controller_zone->SetLED(controller_zone->start_idx() + i, color, Brightness);
                ugui_pset(i/cols, i%cols, color);
            }
        }
    }
}
